import { Body, Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
import { AuthService } from './services/auth.service';
import R from 'src/common/dto/R.dto';
import { EmailService } from './services/email.service';
import { Public } from 'src/common/decorators/auth.decorator';
import { EncryptUtil } from 'src/utils/Encrypt.util';

/**
 * 认证控制器
 */
@Controller('auth')
export class AuthController {
  constructor(
    private readonly authService: AuthService,
    private readonly EmailService: EmailService
  ) {}

  /**
   * 用户登录接口
   *
   * @param body 登录请求体，包含用户名和密码。
   * @returns 如果验证成功，返回包含访问令牌的对象；如果验证失败，返回错误信息。
   */
  @Public()
  @Post('signIn')
  @HttpCode(HttpStatus.OK)
  async signIn(@Body() body: any) {
    // 验证用户身份
    const user = await this.authService.validateUser(body.username, body.password);
    // 如果用户验证失败
    if (!user) {
      return R.fail('用户密码错误！');
    }
    // 生成并返回访问令牌
    const token = this.authService.signIn(user);
    return R.success({
      access_token: token,
    },"登录成功！");
  }

  /**
   * 异步获取公钥
   *
   * @returns 返回一个Promise，该Promise解析为一个结果对象，其中包含获取的公钥。
   */
  @Public()
  @Get('getPublicKey')
  @HttpCode(HttpStatus.OK)
  async getPublicKey() {
    return R.success(await EncryptUtil.getPublicKey());
  }

  /**
   * 请求验证码
   *
   * @param {string} email - 用户的电子邮箱地址。
   * @returns 返回一个Promise，该Promise解析为一个结果对象，其中包含发送验证码的状态。
   */
  @Public()
  @Post('code')
  @HttpCode(HttpStatus.OK)
  async requestCode(@Body('email') email: string) {
    const flag = await this.EmailService.sendVerificationCode(email);
    if (flag) {
      return R.success('已发送至邮箱');
    }

    return R.fail('不存在该邮箱，请检查！');
  }

  /**
   * 验证验证码
   *
   * @param {object} body - 包含用户电子邮箱地址和验证码的请求体。
   * @returns 如果验证成功，返回包含访问令牌的对象；如果验证失败，返回错误信息。
   */
  @Public()
  @Post('verifyCode')
  @HttpCode(HttpStatus.OK)
  async verifyCode(@Body() body: { email: string; code: string }) {
    const { email, code } = body;

    const user = await this.EmailService.verifyCode(email, code);

    if (!user) {
      return R.fail('验证码错误！');
    }

    const token = this.authService.signIn(user);
    return R.success({
      access_token: token,
    });
  }
}
